
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */
package com.hlkj.pay.app.common.ext.aliyun;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponseBody;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.common.MessageExtPt;
import com.hlkj.pay.app.common.ext.ChannelSendDTO;
import com.hlkj.pay.app.common.ext.CommonExtConstant;
import com.hlkj.pay.dto.common.SmsConfig;
import com.hlkj.pay.infrastructure.model.common.TemplateDO;
import darabonba.core.client.ClientOverrideConfiguration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;

/**
 * @author monk@techsun.com
 * @date 2023/04/13 11:58
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = CommonExtConstant.CHANNEL_ALIYUN)
public class AliyunSmsExtPt implements MessageExtPt {
    private Map<String, AsyncClient> clientMap = new ConcurrentHashMap<>();
    @Override
    public String sendMessage(ChannelSendDTO channelSendDTO) {
        TemplateDO templateChannelDTO = channelSendDTO.getTemplateDO();
        if (channelSendDTO.getTestSendMessage()) {
            log.info("TencentSms 短信通道关闭 返回结果:{}",  JsonUtils.toJsonString(channelSendDTO));
            return null;
        } else {
            AsyncClient client = client(channelSendDTO);
            SendSmsRequest sendSmsRequest = SendSmsRequest.builder()
                .templateCode(templateChannelDTO.getTemplateId())
                .templateParam(channelSendDTO.getParams())
                .phoneNumbers(channelSendDTO.getReceiver())
                .signName(channelSendDTO.getSmsConfig().getSign())
                .outId(channelSendDTO.getMessageRequestId())
                .build();
            CompletableFuture<SendSmsResponse> response = client.sendSms(sendSmsRequest);
            try {
                SendSmsResponse sendSmsResponse = response.get();
                log.info("sendMessage sendSmsResponse:{}", JsonUtils.toJsonString(sendSmsResponse));
                SendSmsResponseBody body = sendSmsResponse.getBody();
                if (StringUtils.isBlank(body.getBizId())) {
                    log.warn("sendMessage sendSmsResponse:{}", JsonUtils.toJsonString(sendSmsResponse));
                    return body.getMessage();
                }else {
                   return null;
                }
            } catch (InterruptedException e) {
                //捕获错误异常码
                log.error("AliyunSmsExtPt sendMessage error:{}", e.getMessage(),e);
               return e.getMessage();
            } catch (ExecutionException e) {
                //捕获错误异常码
                log.error("AliyunSmsExtPt sendMessage error:{}", e.getMessage(),e);
                return e.getMessage();
            }
        }
    }
    
    /**
     * client
     * @param secretId
     * @param appSecret
     * @return
     */
    com.aliyun.sdk.service.dysmsapi20170525.AsyncClient client(ChannelSendDTO channelSendDTO) {
        SmsConfig smsConfig = channelSendDTO.getSmsConfig();
        String key = smsConfig.getAppKey() + smsConfig.getSecretKey();
        if (clientMap.containsKey(key)) {
            return clientMap.get(key);
        }
        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                .accessKeyId(smsConfig.getAppKey())
                .accessKeySecret(smsConfig.getSecretKey())
                //.securityToken("<your-token>") // use STS token
                .build());
        
        // Configure the Client
        com.aliyun.sdk.service.dysmsapi20170525.AsyncClient client = AsyncClient.builder()
                // Region ID
                .region("cn-hangzhou")
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(ClientOverrideConfiguration.create().setEndpointOverride("dysmsapi.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();
        clientMap.put(key, client);
        return client;
    }
}
